package com.pc.ipushpin.common.manager;

import com.alibaba.fastjson.JSONObject;
import com.pc.ipushpin.business.model.AppUser;
import com.pc.ipushpin.business.service.impl.AppUserService;
import com.pc.ipushpin.common.util.SignValidator;
import com.pc.ipushpin.common.util.StwConstant;
import com.pc.ipushpin.common.util.WechatUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.mail.internet.MimeUtility;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.io.UnsupportedEncodingException;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
@Transactional
public class AppUserModuleManager {
	
	@Resource
	private AppUserService appUserService;
	
	private static int pageSize = StwConstant.pageSize;
	
	private static String imgService = StwConstant.FILE_SERVER_PATH;
	private static String tomcatPath = "/"+ StwConstant.TOMCAT_ROOT;
	
	private static Logger logger = LoggerFactory.getLogger(AppUserModuleManager.class);

	public Map<String, Object> getWechatInfoByCode(Map<String, String> mapIn, HttpServletRequest request) {
		Map<String,Object> result = new HashMap<String, Object>(10);
		try{
			logger.info("登录获取用户的openId和sessionkey");
			String code = mapIn.get("jsCode");
			mapIn.put("jsCode", code);
			if(!"00".equals(SignValidator.checkEmpty(mapIn).get("resultCode"))){
				return SignValidator.checkEmpty(mapIn);
			}
			Map<String,Object> data = new HashMap<>();
			JSONObject jsonObject = WechatUtil.getSessionKeyForUser(code);
			
			System.out.println(jsonObject);
			
			Object errcode = jsonObject.get("errcode");
			if(errcode != null) {
				data.put("errmsg", jsonObject.get("errmsg"));
				data.put("code", 401);
				result.put("data", data);
				return result;
			}
			
			String openId = (String)jsonObject.get("openid");
			String sessionKey = jsonObject.getString("session_key");
			
			AppUser appUser = appUserService.findUniqueBy("wechatSpOpenId", openId);
			if(appUser == null) {
				appUser = new AppUser();
				appUser.setWechatSpOpenid(openId);
				appUser.setCreateTime(new Date());
				appUserService.save(appUser);
			} 
			
			data.put("sessionKey", sessionKey);
			data.put("openId", appUser.getWechatSpOpenid());
			data.put("userId",appUser.getId());
			
			result.put("data", data);
			result.put("code", 200);
			logger.info("获取用户的openId和sessionkey成功");
		} catch (Exception e) {
			result.put("code", 901);
			logger.error(e.getMessage(), e);
		}
		return result;
	}

	private void getUserInfoByOpenId(String openId,String code) {
		JSONObject accessToken = WechatUtil.getUserAccessToken(StwConstant.WECHAT_SP_APP_ID, StwConstant.WECHAT_SP_APP_KEY, code);
		WechatUtil.getUserInfo(accessToken.toJSONString(), openId);
	}

	public Map<String, Object> getUserInfo(Map<String, String> mapIn, HttpServletRequest request) {
		Map<String, Object> result = new HashMap<>();
		try {
			String openId = mapIn.get("openId");
			mapIn.put("openId", openId);
			if(!"00".equals(SignValidator.checkEmpty(mapIn).get("resultCode"))){
				return SignValidator.checkEmpty(mapIn);
			}
			logger.info("根据小程序的openId判断用户是否存在");
			AppUser appUser = appUserService.findUniqueBy("wechatSpOpenId", openId);
			if(appUser != null) {
				Map<String,Object> user = new HashMap<>();
				user.put("id", appUser.getId());
				user.put("gender", appUser.getGender());
				user.put("nickname",appUser.getNickname());
				user.put("username",appUser.getUsername());
				result.put("code", 200);
			} else {
				result.put("code", 400);
			}
		} catch (Exception e) {
			result.put("code", 901);
			logger.error(e.getMessage(), e);
		}
		return result;
	}

	public Map<String, Object> addUserInfo(Map<String, String> mapIn, HttpServletRequest request) {
		logger.info("addUserInfo:"+mapIn);
		Map<String, Object> result = new HashMap<>();
		try {
			String openId = mapIn.get("openId");
			String telephone = mapIn.get("telephone");
			mapIn.put("openId", openId);
			mapIn.put("telephone", telephone);
			if(!"00".equals(SignValidator.checkEmpty(mapIn).get("resultCode"))){
				return SignValidator.checkEmpty(mapIn);
			}
			AppUser user = appUserService.saveUser(openId,telephone);
			combineUser(user,result);
		} catch (Exception e) {
			result.put("code", 901);
			logger.error(e.getMessage(), e);
		}
		return result;
	}

	public Map<String, Object> decryptUserInfo(Map<String, String> mapIn, HttpServletRequest request) {
		Map<String, Object> result = new HashMap<>();
		try {
			String userId = mapIn.get("userId");
			String sessionKey = mapIn.get("sessionKey");
			String iv = mapIn.get("iv");
			String encryptedData = mapIn.get("encryptedData");
			mapIn.put("sessionKey", sessionKey);
			mapIn.put("iv", iv);
			mapIn.put("encryptedData", encryptedData);
			mapIn.put("userId", userId);
			if(!"00".equals(SignValidator.checkEmpty(mapIn).get("resultCode"))){
				return SignValidator.checkEmpty(mapIn);
			}
			System.out.println("sessionKey:"+sessionKey);
			System.out.println("iv:"+iv);
			System.out.println("encryptedData:"+encryptedData);
			String data = new String(encryptedData.replaceAll(" ", "+"));
			System.out.println("encryptedData:"+data);
			JSONObject jsonObject = WechatUtil.getUserInfo(encryptedData,sessionKey,iv);
			Map<String,Object> userMap = new HashMap<>();
			if(jsonObject != null) {
				System.out.println("解密的用户信息"+jsonObject);
				Map<String,Object> errorMap = new HashMap<>();
				if(jsonObject.get("errcode") != null ) {
					errorMap.put("errmsg", jsonObject.get("errmsg"));
					errorMap.put("code", 401);
					result.put("data", errorMap);
					return result;
				} 
				AppUser appUser = appUserService.findUniqueBy("id", userId);
				if(appUser != null) {
					Object nickName = jsonObject.get("nickName"); //用户昵称
					if(nickName != null) {
						if(!nickName.equals(appUser.getNickname())) {
							String nickNameEncode = MimeUtility.encodeWord((String)nickName);
							appUser.setNickname(nickNameEncode);
						}
					}
					Object avatarUrl = jsonObject.get("avatarUrl"); //用户头像，最后一个数值代表正方形头像大小（有0、46、64、96、132数值可选，0代表132*132正方形头像），用户没有头像时该项为空。若用户更换头像，原有头像URL将失效。
					if(avatarUrl != null ) {
						if(!avatarUrl.equals(appUser.getWechatHeadUrl())) {
							appUser.setWechatHeadUrl((String)avatarUrl);
						}
					}
					Object gender = jsonObject.get("gender"); //用户的性别，值为1时是男性，值为2时是女性，值为0时是未知
					if(gender != null ) {
						if(!gender.equals(appUser.getGender())) {
							appUser.setGender((Integer)gender);
						}
					}
					Object city = jsonObject.get("city"); //用户所在城市
					if(city != null ) {
						if(!city.equals(appUser.getCity())) {
							appUser.setCity((String)city);
						}
					}
					Object province = jsonObject.get("province"); //用户所在省份
					if(province != null ) {
						if(!province.equals(appUser.getProvince())) {
							appUser.setProvince((String)province);
						}
					}
					Object country = jsonObject.get("country"); //用户所在国家
					if(country != null ) {
						if(!country.equals(appUser.getCountry())) {
							appUser.setCountry((String)country);
						}
					}
					Object language = jsonObject.get("language"); //用户的语言，简体中文为zh_CN
					if(language != null ) {
						if(!language.equals(appUser.getLanguage())) {
							appUser.setLanguage((String)language);
						}
					}
					appUser.setLastLoginTime(new Date());
					appUserService.save(appUser);
					userMap.put("userId", appUser.getId());
					if(!StringUtils.isEmpty(appUser.getNickname())) {
						String nickNameDecode = MimeUtility.decodeWord(appUser.getNickname());
						userMap.put("nickName", nickNameDecode);
					}
					userMap.put("avatarUrl", appUser.getWechatHeadUrl());
					userMap.put("city", appUser.getCity());
					userMap.put("province", appUser.getProvince());
					userMap.put("country", appUser.getCountry());
					userMap.put("language", appUser.getLanguage());
					userMap.put("openId", appUser.getWechatSpOpenid());
					result.put("code", 200);
				} else {
					userMap.put("code", 400);
					userMap.put("msg", "用户信息不存在");
				}
			} else {
				userMap.put("errmsg", "解密数据失败");
				userMap.put("code", 401);
				result.put("data", userMap);
				return result;
			}
			result.put("data", userMap);
		} catch (Exception e) {
			result.put("code", 901);
			logger.error(e.getMessage(), e);
		}
		return result;
	}
	
    public String decrypt(String key, String initVector, String encrypted) {
        try {
        	Security.addProvider(new BouncyCastleProvider());
        	byte[] deKey = Base64.decode(key);
        	byte[] deIv = Base64.decode(initVector);
        	byte[] data = Base64.decode(encrypted);
        	System.out.println(data.length);
        	
            SecretKeySpec skeySpec = new SecretKeySpec(deKey, "AES");
            
            AlgorithmParameters params = AlgorithmParameters.getInstance("AES");      
            params.init(new IvParameterSpec(deIv));   

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, params);
            
            byte[] original = cipher.doFinal(data);
            StringBuffer field = new StringBuffer(); 
            for (byte b : original) {
				field.append(b);
			}
            return new String(original);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return null;
    }

	public Map<String, Object> getUserInfoByTel(Map<String, String> mapIn,
			HttpServletRequest request) {
		Map<String, Object> result = new HashMap<>();
		try {
			String telephone = mapIn.get("telephone");
			mapIn.put("telephone", telephone);
			if(!"00".equals(SignValidator.checkEmpty(mapIn).get("resultCode"))){
				return SignValidator.checkEmpty(mapIn);
			}
			logger.info("根据小程序的手机号判断用户是否存在");
			AppUser appUser = appUserService.findUniqueBy("username", telephone);
			combineUser(appUser,result);
		} catch (Exception e) {
			result.put("code", 901);
			logger.error(e.getMessage(), e);
		}
		return result;
	}

	private void combineUser(AppUser user,Map<String,Object> result) {
		if(user != null) {
			Map<String,Object> data = new HashMap<>();
			data.put("userId", user.getId());
			data.put("openId", user.getWechatSpOpenid());
			data.put("telephone", user.getUsername());
			result.put("data", data);
			result.put("code", 200);
		} else {
			result.put("code", 400);
		}
	}

}
